home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 4 / Amiga Tools 4.iso / grafix / raytracing / raylab / source / objects.c < prev    next >
C/C++ Source or Header  |  1996-01-04  |  6KB  |  242 lines

  1. /*
  2.     name:    objects.c
  3.  
  4.     Various object routines
  5.     -----------------------
  6.  
  7. */
  8.  
  9.  
  10. #include  <stdlib.h>
  11.  
  12. #include  "defs.h"
  13. #include  "extern.h"
  14.  
  15.  
  16.  
  17. /*****************************************************************
  18.  *
  19.  *      Calculate the surface-normal for a given point and shape
  20.  *
  21.  *****************************************************************/
  22.  
  23. void GetSurfaceNormal(VECTOR *SurfNorm, POINT *SurfPoint, OBJECT *Object)
  24. {
  25.     PLANE        *p;
  26.     SPHERE        *s;
  27.     ELLIPSOID    *e;
  28.     TRIANGLE    *t;
  29.     BOX        *b;
  30.     DISC        *d;
  31.     CYLINDER    *c;
  32.  
  33.     long        i;
  34.     POINT        ReTransformedPoint;
  35.     VECTOR        tempv;
  36.     double        tempd;
  37.  
  38.     CopyPoint(&ReTransformedPoint,SurfPoint);
  39.  
  40.     if(Object->Transform.NumTransforms>0) {            /* Retransform the surface point */
  41.         for(i=Object->Transform.NumTransforms-1L;i>=0L;i--) {
  42. /*        for(i=0;i<Object->Transform.NumTransforms;i++) { */
  43.         switch(Object->Transform.Entry[i].Type) {
  44.             case TRANSFORM_SCALE:
  45.             ReTransformedPoint.x=ReTransformedPoint.x/Object->Transform.Entry[i].Values.x;
  46.             ReTransformedPoint.y=ReTransformedPoint.y/Object->Transform.Entry[i].Values.y;
  47.             ReTransformedPoint.z=ReTransformedPoint.z/Object->Transform.Entry[i].Values.z;
  48.             break;
  49.             case TRANSFORM_MOVE:
  50.             ReTransformedPoint.x=ReTransformedPoint.x-Object->Transform.Entry[i].Values.x;
  51.             ReTransformedPoint.y=ReTransformedPoint.y-Object->Transform.Entry[i].Values.y;
  52.             ReTransformedPoint.z=ReTransformedPoint.z-Object->Transform.Entry[i].Values.z;
  53.             break;
  54.             case TRANSFORM_ROTATE:
  55.             NegVector(&tempv,&Object->Transform.Entry[i].Values);
  56.             RotatePoint(&ReTransformedPoint,&tempv);
  57.             break;
  58.             case TRANSFORM_NONE:
  59.             default:
  60.             break;
  61.         }
  62.         }
  63.     }
  64.  
  65.     switch(Object->ShapeType) {
  66.     case SHAPE_PLANE:
  67.         p=(PLANE *)(Object->Shape);
  68.         CopyVector(SurfNorm,&(p->Normal));
  69.         break;
  70.     case SHAPE_SPHERE:
  71.         s=(SPHERE *)(Object->Shape);
  72.         SurfNorm->x=ReTransformedPoint.x-s->Centre.x;
  73.         SurfNorm->y=ReTransformedPoint.y-s->Centre.y;
  74.         SurfNorm->z=ReTransformedPoint.z-s->Centre.z;
  75.         break;
  76.     case SHAPE_ELLIPSOID:
  77.         e=(ELLIPSOID *)(Object->Shape);
  78.         SurfNorm->x=(ReTransformedPoint.x-e->Centre.x)/(e->Radius.x*e->Radius.x);
  79.         SurfNorm->y=(ReTransformedPoint.y-e->Centre.y)/(e->Radius.y*e->Radius.y);
  80.         SurfNorm->z=(ReTransformedPoint.z-e->Centre.z)/(e->Radius.z*e->Radius.z);
  81.         break;
  82.     case SHAPE_TRIANGLE:
  83.         t=(TRIANGLE *)(Object->Shape);
  84.         CopyVector(SurfNorm,&(t->Plane.Normal));
  85.         break;
  86.     case SHAPE_BOX:
  87.         b=(BOX *)(Object->Shape);
  88.         if(ReTransformedPoint.x<(b->Corners[0].x+EPSILON))    /* minx */
  89.             CopyVector(SurfNorm,&b->Planes[0].Normal);
  90.         else if(ReTransformedPoint.x>(b->Corners[1].x-EPSILON))    /* maxx */
  91.             CopyVector(SurfNorm,&b->Planes[1].Normal);
  92.         else if(ReTransformedPoint.y<(b->Corners[0].y+EPSILON))    /* miny */
  93.             CopyVector(SurfNorm,&b->Planes[2].Normal);
  94.         else if(ReTransformedPoint.y>(b->Corners[1].y-EPSILON))    /* maxy */
  95.             CopyVector(SurfNorm,&b->Planes[3].Normal);
  96.         else if(ReTransformedPoint.z<(b->Corners[0].z+EPSILON))    /* minz */
  97.             CopyVector(SurfNorm,&b->Planes[4].Normal);
  98.         else if(ReTransformedPoint.z>(b->Corners[1].z-EPSILON))    /* maxz */
  99.             CopyVector(SurfNorm,&b->Planes[5].Normal);
  100.         break;
  101.     case SHAPE_DISC:
  102.         d=(DISC *)(Object->Shape);
  103.         CopyVector(SurfNorm,&(d->Plane.Normal));
  104.         break;
  105.     case SHAPE_CYLINDER:
  106.         c=(CYLINDER *)(Object->Shape);
  107.         tempd=ReTransformedPoint.x*ReTransformedPoint.x+ReTransformedPoint.y*ReTransformedPoint.y;
  108.         if(sqrt(tempd)>(c->r-EPSILON)) {
  109.             SurfNorm->x=ReTransformedPoint.x;
  110.             SurfNorm->y=ReTransformedPoint.y;
  111.             SurfNorm->z=0.0;
  112.         }
  113.         else {
  114.             if(ReTransformedPoint.z<(c->Ends[1].z-EPSILON))
  115.                 CopyVector(SurfNorm,&c->Discs[0].Plane.Normal);
  116.             else CopyVector(SurfNorm,&c->Discs[1].Plane.Normal);
  117.         }
  118.         break;
  119.     }
  120.  
  121.     if(Object->Transform.NumTransforms>0) {            /* Transform the surface normal */
  122. /*        for(i=Object->Transform.NumTransforms-1L;i>=0L;i--) { */
  123.         for(i=0L;i<Object->Transform.NumTransforms;i++) {
  124.         switch(Object->Transform.Entry[i].Type) {
  125.             case TRANSFORM_SCALE:
  126.             SurfNorm->x=SurfNorm->x/Object->Transform.Entry[i].Values.x;
  127.             SurfNorm->y=SurfNorm->y/Object->Transform.Entry[i].Values.y;
  128.             SurfNorm->z=SurfNorm->z/Object->Transform.Entry[i].Values.z;
  129.             break;
  130.             case TRANSFORM_ROTATE:
  131.             CopyVector(&tempv,&Object->Transform.Entry[i].Values);
  132.             RevRotateVector(SurfNorm,&tempv);
  133.             break;
  134.             case TRANSFORM_MOVE:
  135.             case TRANSFORM_NONE:
  136.             default:
  137.             break;
  138.         }
  139.         }
  140.     }
  141. }
  142.  
  143.  
  144.  
  145.  
  146. /*****************************************************************
  147.  *
  148.  *      Free all memory occupied by object-descriptions
  149.  *
  150.  *****************************************************************/
  151.  
  152.  
  153. void FreeAllObjectMemory(void)
  154. {
  155.     long    i;
  156.  
  157.     if(NumObjects>0) {
  158.         for(i=0;i<NumObjects;i++) {
  159.         switch(ObjectArray[i]->ShapeType) {
  160.             case SHAPE_PLANE:
  161.             free((PLANE *)ObjectArray[i]->Shape);
  162.             break;
  163.             case SHAPE_SPHERE:
  164.             free((SPHERE *)ObjectArray[i]->Shape);
  165.             break;
  166.             case SHAPE_ELLIPSOID:
  167.             free((ELLIPSOID *)ObjectArray[i]->Shape);
  168.             break;
  169.             case SHAPE_TRIANGLE:
  170.             free((TRIANGLE *)ObjectArray[i]->Shape);
  171.             break;
  172.             case SHAPE_BOX:
  173.             free((BOX *)ObjectArray[i]->Shape);
  174.             break;
  175.             case SHAPE_DISC:
  176.             free((DISC *)ObjectArray[i]->Shape);
  177.             break;
  178.             case SHAPE_CYLINDER:
  179.             free((CYLINDER *)ObjectArray[i]->Shape);
  180.             break;
  181.         }
  182.         free(ObjectArray[i]);
  183.         ObjectArray[i]=NULL;
  184.         }
  185.     }
  186.  
  187.     if(NumLights>0) {
  188.         for(i=0;i<NumLights;i++) {
  189.         free(LightArray[i]);
  190.         LightArray[i]=NULL;
  191.         }
  192.     }
  193. }
  194.  
  195.  
  196.  
  197. /*****************************************************************
  198.  *
  199.  *      Transform handling routines
  200.  *
  201.  *****************************************************************/
  202.  
  203.  
  204. void ClearTransform(TRANSFORM *t)
  205. {
  206.     int    i;
  207.  
  208.     t->NumTransforms=0L;
  209.     for(i=0;i<10;i++) {
  210.         t->Entry[i].Type=TRANSFORM_NONE;
  211.         t->Entry[i].Values.x=t->Entry[i].Values.y=t->Entry[i].Values.z=0.0;
  212.     }
  213. }
  214.  
  215.  
  216. void CopyTransform(TRANSFORM *t2, TRANSFORM *t1)
  217. {
  218.     int    i;
  219.  
  220.     t2->NumTransforms=t1->NumTransforms;
  221.     for(i=0;i<10;i++) {
  222.         t2->Entry[i].Type=t1->Entry[i].Type;
  223.         CopyVector(&t2->Entry[i].Values,&t1->Entry[i].Values);
  224.     }
  225. }
  226.  
  227.  
  228. void AddTransform(TRANSFORM *t2, TRANSFORM *t1)
  229. {
  230.     long    i,orignumtrans;
  231.  
  232.     orignumtrans=t2->NumTransforms;
  233.     t2->NumTransforms+=t1->NumTransforms;
  234.     if(t2->NumTransforms>10L) t2->NumTransforms=10L;
  235.     for(i=orignumtrans;i<t2->NumTransforms;i++) {
  236.         t2->Entry[i].Type=t1->Entry[i].Type;
  237.         CopyVector(&t2->Entry[i].Values,&t1->Entry[i].Values);
  238.     }
  239. }
  240.  
  241.  
  242.